#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <glib.h>
#include <glib/gprintf.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include "commandes.h"



int main(int argc, char *argv[]) {
  // 

  struct sigaction sa;
  sigaction(SIGCHLD, NULL, &sa);
  sa.sa_flags = SA_SIGINFO|SA_NOCLDSTOP|SA_RESTART;
  sa.sa_sigaction = traitement_signal_fils;
  
  sigaction(SIGCHLD, &sa, NULL);

  while (1) {
    int attend;
    char **tab_com_pipe = NULL;
    char **arg_com1 = NULL;
    char **arg_com2 = NULL;
    char *text_com = NULL;
    size_t taille_com = 0;
    ssize_t res;

    //    text_com = readline("entrez une commande>");
    fprintf(stdout, "entrez une commande>");
    fflush(stdout);

    res = getline(&text_com, &taille_com, stdin);
    if (res < 0) {
      perror("problÃ¨me de lecture sur la ligne de commande");
      exit(1);
    }
    if (text_com != NULL) {

      g_strdelimit(text_com, "\t\n", ' ');
      g_strstrip(text_com);

      fprintf(stderr, "lecture de la commande \"%s\"\n", text_com);
      if (strcmp(text_com, "fin")==0) {
	// Si la commande est "fin" on termine le shell
	fprintf(stderr, "bye\n");
	free(text_com);
	break;
      }

      if (strlen(text_com) == 0) {
	// si la chaine est vide.
	fprintf(stderr, "La comande est vide\n");
	free(text_com);
	continue;
      }
      
      if (text_com[strlen(text_com)-1] == '&') {
	// il y a un & Ã  la fin
	// on doit faire une commande en tÃ¢che de fond.
	attend = false;
	text_com[strlen(text_com)-1] = '\0';
	g_strstrip(text_com);
      } else {
	// Le shell devra attendre la fin de la commande
	attend = true;
      }
      
      tab_com_pipe = g_strsplit(text_com, "|", -1);
      
      
      if (g_strv_length(tab_com_pipe) == 1) {
	pid_t pid_com;
  
	// il n'y a pas de pipe, une seule commande Ã  traiter

	arg_com1 = g_strsplit_set(tab_com_pipe[0], "\t ", -1);

	// ######################################
	// Code Ã  modifier ici
	// ######################################
	// vous devez appeler la fonction execvp avec les arguments identiques Ã  executevp
	// de maniÃ¨re Ã  ce que le shell execute la commande en premier plan si attend = true
	// en tÃ¢che de fond sinon

	pid_com = fork();
	if (pid_com < 0) {
	  perror("Il y a eu un problÃ¨me durant le fork()");
	  exit(1);
	}
	if (pid_com == 0) {
	  fprintf(stderr, "lancement de %s\n", text_com);
	  execvp(arg_com1[0], arg_com1);
	  fprintf(stderr, "erreur avec la commande %s car : %s\n", text_com, strerror(errno));
	  exit(2);
	} else {

	  if (attend) {
	    attente_fils(pid_com);
	  } else {
 
	    //	    fprintf(stdout, "En tÃ¢che de fond\n");	  
	  }
	}
	

      }
      else if (g_strv_length(tab_com_pipe) == 2) {
	// il y a un seul pipe
	g_strstrip(tab_com_pipe[0]);
	g_strstrip(tab_com_pipe[1]);
	
	arg_com1 = g_strsplit_set(tab_com_pipe[0], "\t ", -1);
	arg_com2 = g_strsplit_set(tab_com_pipe[1], "\t ", -1);
	// ######################################
	// Code Ã  modifier ici
	// ######################################
	// vous devez appeler la fonction execvp avec les arguments identiques Ã  executevp
	// de maniÃ¨re Ã  ce que le shell execute les deux  commandes avec un pipe entre elle
	executevp(arg_com1[0], arg_com1);
	fprintf(stdout, "Dont la sortie est redirigÃ©e vers\n");
	executevp(arg_com2[0], arg_com2);

	if (attend) {
	  fprintf(stdout, "Au premier plan\n");
	} else {
	  fprintf(stdout, "En tache de fond\n");	  
	}	
	
      } else {
	fprintf(stderr, "Je ne sais pas faire Ã§a\n");
	exit(1);
      }
      

      if (tab_com_pipe != NULL) {
	g_strfreev(tab_com_pipe);
      }
      if (arg_com1 != NULL) {
	g_strfreev(arg_com1);
      }
      if (arg_com2 != NULL) {
	g_strfreev(arg_com2);
      }
      if (text_com != NULL) {
	free(text_com);
      }
    }
    
    
  }   

  return 0;
}
